package monitormercado.apresentacao.tela.simulacao;

import java.util.Date;
import java.util.List;

import monitormercado.framework.Controlador;
import monitormercado.framework.ILogListener;
import monitormercado.negocio.Tick.ControladorTick;
import monitormercado.negocio.Tick.Tick;
import monitormercado.negocio.analise.estrategia.EstrategiaAlugueis;
import monitormercado.negocio.analise.estrategia.EstrategiaBuyHold;
import monitormercado.negocio.analise.estrategia.EstrategiaCandles;
import monitormercado.negocio.analise.estrategia.EstrategiaEstocastico;
import monitormercado.negocio.analise.estrategia.EstrategiaMediasMoveis;
import monitormercado.negocio.analise.estrategia.EstrategiaTripleScreen;
import monitormercado.negocio.analise.estrategia.EstrategiaVolumesAtipicos;
import monitormercado.negocio.analise.estrategia.simulacao.ResultadoCombinadoSimulacao;
import monitormercado.negocio.analise.estrategia.simulacao.Simulador;
import monitormercado.negocio.analise.indicador.stochastic.GeradorEstocastico;
import monitormercado.util.Configuracao;
import monitormercado.util.Cronometro;

public class ControladorSimulacao extends Controlador {

	public ResultadoCombinadoSimulacao simular(List<ComandoSimular> comandos, ILogListener logListener) {
		
		Cronometro cronometro = new Cronometro();
		cronometro.iniciarContagem();
		
		ControladorTick controladorTick = new ControladorTick();
		Simulador simulador = new Simulador();
		if (logListener != null) {
			simulador.incluirListener(logListener);
		}
		
		ResultadoCombinadoSimulacao resultadoSimulacao = new ResultadoCombinadoSimulacao();
//		List<String> acoes = UtilIO.carregarListaAtivos();
		List<String> acoes = Configuracao.getListaAtivos();

		for (String siglaAcao : acoes) {
			List<Tick> ticks = controladorTick.recuperarTodosTicksPorData(siglaAcao);
			try {
				for (ComandoSimular comando : comandos) {
					comando.simular(siglaAcao, ticks, simulador, resultadoSimulacao);
				}
				
				resultadoSimulacao.calcularDiferencaBenchmark(siglaAcao);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		resultadoSimulacao.calcularEstatisticas();
		cronometro.finalizarContagem();
		return resultadoSimulacao;
	}

	public ComandoSimular novoComandoSimularEstocastico(Double limiteInferior, Double limiteSuperior, Double stop, Date dataInicial, Date dataFinal) {
		EstrategiaEstocastico estrategiaEstocastico =  new EstrategiaEstocastico(new GeradorEstocastico(), 14, 3, limiteInferior, limiteSuperior);
		return new ComandoSimular(estrategiaEstocastico, stop, dataInicial, dataFinal);
	}

	public ComandoSimular novoComandoSimularBuyAndHold(Date dataInicial, Date dataFinal) {
		return new ComandoSimular(new EstrategiaBuyHold(), null, dataInicial, dataFinal);
	}

	public ComandoSimular novoComandoSimularMediasMoveis(Integer emaCurta, Integer emaLonga, Integer periodicidade, Double stop, Date dataInicial, Date dataFinal) {
		EstrategiaMediasMoveis estrategiaMediasMoveis = new EstrategiaMediasMoveis();
		estrategiaMediasMoveis.setNumeroAmostrasEMACurta(emaCurta);
		estrategiaMediasMoveis.setNumeroAmostrasEMALonga(emaLonga);
		estrategiaMediasMoveis.setPeriodicidade(periodicidade);

		return new ComandoSimular(estrategiaMediasMoveis, stop, dataInicial, dataFinal);
	}

	public ComandoSimular novoComandoSimularTripleScreen(double stop, Date dataInicial, Date dataFinal) {
		return new ComandoSimular(new EstrategiaTripleScreen(), stop, dataInicial, dataFinal);
	}

	public ComandoSimular novoComandoSimularAlugueis(double stop, Date dataInicial, Date dataFinal) {
		return new ComandoSimular(new EstrategiaAlugueis(), stop, dataInicial, dataFinal);
	}

	public ComandoSimular novoComandoSimularCandles(double stop, Date dataInicial, Date dataFinal) {
		return new ComandoSimular(new EstrategiaCandles(), stop, dataInicial, dataFinal);
	}
	
	public ComandoSimular novoComandoSimularVolumesAtipicos(Integer ema, Integer periodicidade, Double fator, Double stop, Date dataInicial, Date dataFinal) {
		EstrategiaVolumesAtipicos estrategiaVolumesAtipicos = new EstrategiaVolumesAtipicos();
		estrategiaVolumesAtipicos.setNumeroAmostrasEMA(ema);
		estrategiaVolumesAtipicos.setPeriodicidade(periodicidade);
		estrategiaVolumesAtipicos.setFator(fator);

		return new ComandoSimular(estrategiaVolumesAtipicos, stop, dataInicial, dataFinal);
	}

}
